// 地图标签：
//	<No Shadow>			此地图不显示阴影
//	<Shadow Angle: x>	阴影角度（范围：-180~180，默认为-45。）
//                      角色朝上时为0°，向左偏为负，向右偏为正。向下时角度超过90°
//=============================================================================
// 显示行走图阴影（参考Drill_LayerReverseReflection）
//=============================================================================
import { CharacterShadowParams as characterShadowList } from '@swda/configs/params'
let SWDA_CharacterShadow = {};

//=============================================================================
// ** 事件
//=============================================================================
//==============================
// * 事件 - 注释设置
//==============================
SWDA_CharacterShadow.Game_Event_SetupPage = Game_Event.prototype.setupPage;
Game_Event.prototype.setupPage = function () {
	SWDA_CharacterShadow.Game_Event_SetupPage.call(this);
	this.setupCharacterShadow();
};
Game_Event.prototype.setupCharacterShadow = function () {
	if (this.event().meta) {
		this._isShadow = (this.event().meta['no shadow'] || false) == false;
	}
};



//=============================================================================
// ** 物体
//=============================================================================
//==============================
// * 物体初始化
//==============================
SWDA_CharacterShadow.initMembers = Game_CharacterBase.prototype.initMembers;
Game_CharacterBase.prototype.initMembers = function () {
	SWDA_CharacterShadow.initMembers.call(this);
	this._isShadow = true;
};
//==============================
// * 获取 - 反射
//==============================
Game_CharacterBase.prototype.isShadow = function () {
	return this._isShadow;
};

//==============================
// * 固定帧初始值
//==============================
/*
SWDA_CharacterShadow.Sprite_Character_UpdatePosition = Sprite_Character.prototype.updatePosition;
Sprite_Character.prototype.updatePosition = function() {
	SWDA_CharacterShadow.Sprite_Character_UpdatePosition.call(this);
	if( this.rotation != 0 ){ this.rotation = 0; }
	if( this.scale.x != 1 ){ this.scale.x = 1; }
	if( this.scale.y != 1 ){ this.scale.y = 1; }
	if( this.skew.x != 0 ){ this.skew.x = 0; }
	if( this.skew.y != 0 ){ this.skew.y = 0; }
	//从这里开始，参数都被固定值（不需要考虑多次update的叠加影响）
};
*/

//=============================================================================
// ** 地图
//=============================================================================
//==============================
// * 地图 - 建立镜像（Tilemap层）
//==============================
SWDA_CharacterShadow.Spriteset_Map_CreateTilemap = Spriteset_Map.prototype.createTilemap;
Spriteset_Map.prototype.createTilemap = function () {
	SWDA_CharacterShadow.Spriteset_Map_CreateTilemap.call(this);
	if ($dataMap.meta && $dataMap.meta["No Shadow"]) return;
	this.createCharacterShadow();

};
Spriteset_Map.prototype.createCharacterShadow = function () {
	let originChacterContainer = []
	originChacterContainer.push(...$gameMap.events())// 事件
	originChacterContainer.push(...$gamePlayer.followers()._data)// 跟随队员
	originChacterContainer.push($gamePlayer)// 玩家

	this._characterShadowSprites = [];
	this._characterShadowLayer = new Sprite();
	this._characterShadowLayer.z = 1; // z轴：1.事件下方 3.事件相同 5.事件上方 6.影子 7.气泡 8.动画层 9.鼠标目的地

	originChacterContainer.forEach(item => {
		const shadowSprite = new Sprite_CharacterShadow(item)
		this._characterShadowSprites.push(shadowSprite)
		this._characterShadowLayer.addChild(shadowSprite)
	})

	this._tilemap.addChild(this._characterShadowLayer);

};
//==============================
// * 地图 - 确认物体数量
//==============================
SWDA_CharacterShadow.Spriteset_Map_CreateCharacters = Spriteset_Map.prototype.createCharacters;
Spriteset_Map.prototype.createCharacters = function () {
	SWDA_CharacterShadow.Spriteset_Map_CreateCharacters.call(this);
	this._charSpriteLen = this._characterSprites.length;	//>记录物体数量
};
//==============================
// * 帧刷新 - 新事件的倒影
//==============================
SWDA_CharacterShadow.Spriteset_Map_Update = Spriteset_Map.prototype.update;
Spriteset_Map.prototype.update = function () {
	SWDA_CharacterShadow.Spriteset_Map_Update.call(this);
	this.updateNewEventShadow();
}
Spriteset_Map.prototype.updateNewEventShadow = function () {
	//if($gameMap._drill_LRR_enable != true){ return; }

	if (this._characterSprites.length <= this._charSpriteLen) return;

	for (let i = this._charSpriteLen; i < this._characterSprites.length; i++) {
		const temp_sprite = new Sprite_CharacterShadow(this._characterSprites[i]._character);
		this._characterShadowSprites.push(temp_sprite);
		this._characterShadowLayer.addChild(temp_sprite);
	}
	this._characterSprites = this._characterSprites.length;
}


//=============================================================================
// ** 阴影贴图类（直接继承玩家贴图）
//=============================================================================
function Sprite_CharacterShadow() {
	this.initialize.apply(this, arguments);
}
Sprite_CharacterShadow.prototype = Object.create(Sprite_Character.prototype);
Sprite_CharacterShadow.prototype.constructor = Sprite_CharacterShadow;

//==============================
// * 初始化
//==============================
Sprite_CharacterShadow.prototype.initialize = function (character) {
	Sprite_Character.prototype.initialize.call(this, character);
	this.opacity = 0;
	this._destroyed = false;
	this._isSpecialCharacter = false;
	this._specialCharacter = null;
};

//==============================
// * 优化 - 镜头之外的事件，不刷新镜像
//==============================
Sprite_CharacterShadow.prototype.isNearTheScreen = function () {
	if (!this._character) return false; //无事件的贴图直接跳过

	const gw = Graphics.width + 48 * 4;		//加宽识别范围
	const gh = Graphics.height + 48 * 4;
	const tw = $gameMap.tileWidth();
	const th = $gameMap.tileHeight();
	const px = this._character.scrolledX() * tw + tw / 2 - gw / 2;
	const py = this._character.scrolledY() * th + th / 2 - gh / 2;
	return px >= -gw && px <= gw && py >= -gh && py <= gh;
}

//==============================
// * 阴影偏移量Y
//==============================

Sprite_CharacterShadow.prototype.angle = function () {
	if ($dataMap.meta && $dataMap.meta["Shadow Angle"]) {
		var shadowAngle = Number($dataMap.meta["Shadow Angle"]);
		return shadowAngle;
	}
	return -45;	//范围：-180,180
}
Sprite_CharacterShadow.prototype.offsetY = function () {
	if (this._isSpecialCharacter) {
		if (this._specialCharacter.OffsetY)
			return this._specialCharacter.OffsetY;
	}
	return 12;  //行走图阴影纵轴锚点（脚底到分块底部边缘的距离）
}

Sprite_CharacterShadow.prototype.offsetX = function () {
	if (this._isSpecialCharacter) {
		if (this._specialCharacter.OffsetX)
			return this._specialCharacter.OffsetX;
	}
	return 0;	//行走图阴影横轴锚点
}

Sprite_CharacterShadow.prototype.setSpecialCharacter = function () {
	var characterName = this._characterName;
	var specialCharacter = characterShadowList.filter(function (character) {
		return character.Name === characterName;
	})[0];

	if (specialCharacter) {
		this._isSpecialCharacter = true;
		this._specialCharacter = specialCharacter;
	} else {
		this._isSpecialCharacter = false;
		this._specialCharacter = null;
	}
}

Sprite_CharacterShadow.prototype.isShadowVisible = function () {
	// 性能优化：移动端不显示阴影
	if (Utils.isMobileDevice() || !ConfigManager.characterShaddow){
		return false;
	}

	if (this._isSpecialCharacter){
		if (!this._specialCharacter.show)
		return false;
	}
	return true;	//行走图阴影是否显示
}

//==============================
// * 帧刷新
//==============================
Sprite_CharacterShadow.prototype.update = function () {
	//若该行走图不显示阴影，则直接关闭update
	if (!this.isShadowVisible()) {
		this.visible = false;
		return;
	}

	//不在镜头范围内，直接关闭update（能直接节省210ms左右性能）
	if (!this.isNearTheScreen()) {
		this.visible = false;
		return;
	}

	// hitbox虚拟事件，若设为隐藏，则同时隐藏阴影
	if (Imported.CP_X_AnalogMove) {
		if (this.isVirtualEventCharacter()) {
			if (!this._character._baseEvent._showVirtualEvent) {
				this.visible = false;
				return;
			}
		}
	}

	
	Sprite_Character.prototype.update.call(this);
	this.updateShadow()
};

/***************************
 * 渲染阴影
 ***************************/
Sprite_CharacterShadow.prototype.updateShadow = function () {
	//可见度、透明度
	this.opacity = Math.round(this._character.opacity() / 3);
	this.visible = this._character.isShadow() && !this._destroyed;
	if (this._character._transparent === true) this.visible = false;

	if (!this.visible || this.opacity === 0) return;

	this.anchor.x = 0.5 + this.offsetX() / this.patternWidth();
	this.anchor.y = 1 - this.offsetY() / this.patternHeight();
	const angle = this.angle();
	const angleRad = Math.PI * (angle / 180);

	// 角度
	if (angle <= 60 && angle >= -60) {
		this.skew.x = -angleRad;
		if (angle > 0) {
			this.scale.y *= (1 - 0.2 * (Math.abs(60 - angle) / 60));
		} else {
			this.scale.y *= (1 - 0.2 * (Math.abs(-60 - angle) / 60));
		}
	} else if ((angle <= -120 && angle > -180) || (angle >= 120 && angle < 180)) {
		this.skew.x = -angleRad;
		if (angle > 0) {
			this.scale.y *= (1 - 0.2 * (Math.abs(120 - angle) / 60));
		} else {
			this.scale.y *= (1 - 0.32 * (Math.abs(-120 - angle) / 60));
		}
	} else if (angle == 180 || angle == -180) {
		this.scale.y *= -0.8;
	} else {
		this.scale.x *= 0.6;
		this.scale.x *= 0.8;
		if (angle > 0) {
			this.rotation = Math.PI / 2;
			this.skew.x = Math.PI / 2 - angleRad;
		} else {
			this.rotation = -Math.PI / 2;
			this.skew.x = -Math.PI / 2 - angleRad;
		}
	}

	//位移
	const real_fix_y = Math.round((this._character.scrolledY() + 1) * $gameMap.tileHeight() - this._character.shiftY() + this._character.spriteOffsetY());
	this.y = real_fix_y - this.y + real_fix_y - this.offsetY() * Math.abs(this.scale.y);
	this.x += - this.offsetX() * this.scale.x + this._character.spriteOffsetX();
	// 修正y轴尺寸
	this.scale.y *= 0.75;
	this.scale.x *= 0.9;
}

Sprite_CharacterShadow.prototype.createHalfBodySprites = function () {
	if (!this._upperBody) {
		this._upperBody = new Sprite();
		this._upperBody.anchor.x = 0.5;
		this._upperBody.anchor.y = 1;
		this._upperBody.opacity = 128;
		this.addChild(this._upperBody);
	}
	if (!this._lowerBody) {
		this._lowerBody = new Sprite();
		this._lowerBody.anchor.x = 0.5;
		this._lowerBody.anchor.y = 1;
		this._lowerBody.opacity = 128;
		this.addChild(this._lowerBody);
	}
};

const _Sprite_CharacterShadow_SetCharacterBitmap = Sprite_CharacterShadow.prototype.setCharacterBitmap;
Sprite_CharacterShadow.prototype.setCharacterBitmap = function () {
	_Sprite_CharacterShadow_SetCharacterBitmap.call(this);
	//>颜色
	this.setSpecialCharacter();
	this.setBlendColor([0, 0, 0, 255]);
};

//==============================
// * 去掉影响的部分
//==============================
Sprite_CharacterShadow.prototype.updateAnimation = function () { }	//动画遮挡
Sprite_CharacterShadow.prototype.updateBalloon = function () { }	//气泡遮挡
